/*
 *  Copyright 2013 Utkin Dmitry
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifndef PROTOQTRPC_SOCKETRPCSERVER_H
#define PROTOQTRPC_SOCKETRPCSERVER_H

#include <QObject>
#include "RpcServer.h"

namespace google {
namespace protobuf {
class Service;
}
}

namespace protoqtrpc
{

class SocketRpcServerSession;
class SocketRpcServerPrivate;

/**
 * @brief The SocketRpcServer class
 * Implements RPC Server on socket transport
 */
class SocketRpcServer: public QObject, public RpcServer
{
    Q_OBJECT

public:
    /**
     * @brief Constructs SocketRpcServer
     */
    SocketRpcServer();

    /**
     * @brief Destroys SocketRpcServer
     */
    virtual ~SocketRpcServer();

    /**
     * @brief Sets port for incomming connections
     * @param port Port for incomming connections
     */
    virtual void setPort(quint16 port);

    /**
     * @brief Gets port on which server is started
     * @return Port for incomming connections
     */
    quint16 port() const;

    /**
     * @brief Registers the service and add it into services list
     * @param service Service to register
     * @return true if servuce was sucessfully registered
     */
    virtual bool registerService(::google::protobuf::Service* service);

    /**
     * @brief Gets registered service by full qualified name
     * @param serviceName Full qualified service name
     * @return Pointer to found Service or NULL, if no service found
     */
    virtual ::google::protobuf::Service* getService(const std::string& serviceName);

    /**
     * @brief Try to start server, if server is not started check the errorString()
     * @return true if server was started successfully
     * @sa errorString()
     */
    virtual bool start();

    /**
     * @brief Stops the started server
     */
    virtual void stop();

    /**
     * @brief Get last error string
     * @return last error string
     */
    virtual QString errorString() const;

protected slots:
    /**
     * @brief Accepts new incomming connection from client and creates new session
     */
    void acceptConnection();

    /**
     * @brief Close finished connection and frees associated data
     * @param obj Connection object
     */
    void closeConnection(QObject* obj);

private:
    Q_DECLARE_PRIVATE(SocketRpcServer)
    Q_DISABLE_COPY(SocketRpcServer)
    SocketRpcServerPrivate* d_ptr;
};

}

#endif
